﻿using System.IO.IsolatedStorage;
using System.Windows;
using System;
using System.Collections.Generic;

namespace DeenGames.Utils
{
    ///<summary>
    /// Represents an abstract storage class, for use in Silverlight. Persistent
    /// means that storage persists over multiple invocations of your application.
    /// So if you load an app, store something, and refresh, it's still there.
    /// If IsolatedStorage is available, use that; if not, use cookies.
    /// We also encrypt stored data (if it's not cookie-based storage), and we
    /// hash variable names to prevent tampering.
    /// 
    /// TODO: consider adding fingerprinting with a hash digest; is it worth it?
    /// 
    /// This open-source module brought to you by Deen Games
    /// See http://developer.deengames.com for more details.
    ///</summary>
    public static class PersistentStorage
    {

        //private static IPersistentStorageProvider _provider;
        private static bool _usingCookieStorage = false;

        // Try and use Isolated Storage; fall back to cookies.
        static PersistentStorage()
        {
            try
            {
                Provider = new IsolatedStorageProvider();
            }
            catch (IsolatedStorageException e)
            {
                // Isoalted Storage is disabled. Use cookies.
                _usingCookieStorage = true;
                Provider = new CookieStorageProvider();

                // get XAP file to use as partial key
                string key = Application.Current.Host.Source.AbsoluteUri;
                int start = key.LastIndexOf("/") + 1;
                int end = key.LastIndexOf(".");
                key = key.Substring(start, end - start);
                PersistentStorageHelper.appIdentifier = string.Format("[{0}] ", key);
            }
        }

        /// <summary>
        /// Are we forced to use cookies for storage? If so, and if your app stores
        /// a lot of information, saving may crap out; so check this.
        /// </summary>
        public static bool IsUsingCookieStorage { get { return _usingCookieStorage; } }

        ///<summary>
        /// Put an item into the store; we reference it by key. If the item is already there,
        /// overwrite it. Throw an exception if we're out of space and can't store the value.
        /// @throws InvalidOperationException if we are out of space and cannot write the value.
        ///</summary>
        public static string Store<_type>(string key, _type value)
        {
            return Provider.Store(key, value);
        }

        public static void Remove(string key)
        {
            Provider.Remove(key);
        }

        ///<summary>
        /// Get an item from the store, using the key-name.
        /// Returns null if no object exists in storage with that key.
        ///</summary>
        public static _type Retrieve<_type>(string key)
        {
            _type item = Provider.Retrieve<_type>(key);
            if (item == null) return default(_type);
            if (item is _type) return item;
            throw new Exception("item " + key + " was not of the expected type");
        }

        public static IEnumerable<string> Files { get { return Provider.Keys; } }

        ///<summary>
        /// Deletes EVERYTHING stored for our application.
        /// Use with care; put behind a confirmation screen.
        ///</summary>
        public static void Clear()
        {
            Provider.Clear();
        }

        public static IPersistentStorageProvider Provider { get; set; }
    }
}
